/**
 * 图表渲染通用混入
 * 提供统一的图表创建、管理和清理功能
 * 基于原始 index.vue.backup 文件中的 renderChart 方法重构
 */
import * as echarts from 'echarts'

export default {
  data() {
    return {
      // ECharts 实例管理
      chartInstances: {},
      // 图表容器尺寸监听器
      chartResizeObservers: {},
      // 窗口resize处理器（防抖）
      windowResizeHandler: null
    }
  },
  
  mounted() {
    // 初始化窗口resize监听
    this.initWindowResize()
  },
  
  beforeDestroy() {
    // 清理所有资源
    this.cleanup()
  },
  
  methods: {
    /**
     * 统一图表渲染方法
     * @param {string} containerId - 图表容器ID
     * @param {Object} option - ECharts配置选项
     */
    renderChart(containerId, option) {
      const container = document.getElementById(containerId)
      if (!container) {
        console.warn(`图表容器未找到: ${containerId}`)
        return
      }

      // 清理旧实例与观察器
      if (this.chartInstances[containerId]) {
        this.chartInstances[containerId].dispose()
        this.chartInstances[containerId] = null
      }
      if (this.chartResizeObservers[containerId]) {
        try {
          this.chartResizeObservers[containerId].disconnect()
        } catch (e) {
          console.warn('断开图表尺寸监听器失败:', e)
        }
        delete this.chartResizeObservers[containerId]
      }

      // 初始化图表
      const chart = echarts.init(container)
      chart.setOption(option, true)
      this.chartInstances[containerId] = chart

      // 关键1：等一帧再 resize，确保容器完成布局
      requestAnimationFrame(() => chart && chart.resize())

      // 关键2：监听容器或其父容器尺寸变化，自动 resize（防抖）
      const ro = new ResizeObserver(this._debounce(() => {
        chart && chart.resize()
      }, 120))
      const observeTarget = container.parentElement || container
      ro.observe(observeTarget)
      this.chartResizeObservers[containerId] = ro
    },

    /**
     * 初始化窗口resize监听
     */
    initWindowResize() {
      this.windowResizeHandler = this._debounce(() => {
        Object.values(this.chartInstances).forEach(chart => chart && chart.resize())
      }, 120)
      window.addEventListener('resize', this.windowResizeHandler)
    },

    /**
     * 清理所有资源
     */
    cleanup() {
      // 销毁所有图表实例
      Object.values(this.chartInstances).forEach(chart => {
        if (chart) {
          chart.dispose()
        }
      })
      this.chartInstances = {}

      // 清理窗口resize监听器
      if (this.windowResizeHandler) {
        window.removeEventListener('resize', this.windowResizeHandler)
        this.windowResizeHandler = null
      }

      // 清理所有ResizeObserver
      Object.values(this.chartResizeObservers).forEach(observer => {
        try {
          observer.disconnect()
        } catch (e) {
          console.warn('断开图表尺寸监听器失败:', e)
        }
      })
      this.chartResizeObservers = {}
    },

    /**
     * 通用防抖方法
     * @param {Function} fn - 要防抖的函数
     * @param {number} wait - 防抖延迟时间（毫秒）
     * @returns {Function} 防抖后的函数
     */
    _debounce(fn, wait = 100) {
      let t = null
      return (...args) => {
        if (t) clearTimeout(t)
        t = setTimeout(() => fn.apply(this, args), wait)
      }
    },

    /**
     * 格式化金额显示：保留2位小数
     * @param {number|string} amount - 金额
     * @returns {string} 格式化后的金额
     */
    formatAmount(amount) {
      if (!amount || isNaN(amount)) return '0.00'
      return Number(amount).toFixed(2)
    },

    /**
     * 金额格式化：整数不带小数，小数保留两位，带¥前缀
     * @param {number|string} amount - 金额
     * @returns {string} 格式化后的金额（带¥前缀）
     */
    formatAmountYuan(amount) {
      const n = Number(amount)
      if (!isFinite(n)) return '¥0'
      return Math.floor(n) === n ? `¥${n}` : `¥${n.toFixed(2)}`
    },

    /**
     * 简单日期格式化：返回 yyyy-MM-dd
     * @param {Date} date - 日期对象
     * @returns {string} 格式化后的日期字符串
     */
    formatDate(date) {
      const y = date.getFullYear()
      const m = String(date.getMonth() + 1).padStart(2, '0')
      const d = String(date.getDate()).padStart(2, '0')
      return `${y}-${m}-${d}`
    }
  }
}